/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package frontierserver;

/**
 *
 * @author andrew
 */

import java.io.*;

import java.net.*;
import java.util.*;

public class TCPServer {



        // the socket used by the server

        public ServerSocket tcpSock;
        public Vector<TcpClient> clientList = new Vector<TcpClient>();
        public static  Vector<player> playerList = new Vector<player>();
        String outbound = new String();



        TCPServer(int port) {

                try

                {

                        tcpSock = new ServerSocket(port);
                        int z = 0;
                        while(true)

                        {

                                Socket sock = tcpSock.accept();
                                sock.setKeepAlive(true);

                                clientList.addElement(new TcpClient(sock));
                                clientList.get(z).cr.start();
                                clientList.get(z).cw.start();
                                clientList.get(z).packs.addElement("?");
                                while(!clientList.get(z).cr.nameRecieved)
                                {
                                //do nothing untill client has provided it's name
                                }
                                playerList.addElement(new player(sock.getInetAddress(), clientList.get(z).cr.playerName));

                                
                                playerList.get(z).id=z;
                                playerList.get(z).name=clientList.get(z).cr.playerName;
                                clientList.get(z).packs.addElement("2 " + z);
                                for(int j =0; j<playerList.size();j++)
                                    {
                                        addToQueue("3 " + playerList.get(j).id + " "
                                                + playerList.get(j).name + " " + playerList.get(j).x + " " + playerList.get(j).y + " " + 
                                                playerList.get(j).area + " ");
                                    }
                                z++;
                                addToQueue("4 " + z);
                        }

                }

                catch (IOException e) {

                        System.out.print(e);

                }

        }
        
        public void addToQueue(String packe)
        {
            for(int i = 0; i<clientList.size();i++)
            {
                if(playerList.get(i).Connected){
                System.out.print(clientList.get(i).sock.getInetAddress().toString() + ": adding " + packe + '\n');
                clientList.get(i).packs.addElement(packe);
                }

            }
        }

        public class player {
            public String name;
            public int id;
            public InetAddress ip;
            public double x;
            public double y;
            public int area;
            public boolean Connected;
            player(InetAddress i){
                ip = i;
                x =  30.000;
                y = 15.015;
                area = 0;
                Connected = true;
            }
            player(InetAddress i, String n){
                ip = i;
                x =  30.000;
                y = 15.015;
                area = 0;
                Connected = true;
                name = n;
            }
            player(){
                 x =  30.000;
                y = 15.015;
                area = 0;
                Connected = true;
            }
        }


        /** One instance of this thread will run for each client */

       public class TcpClient {

//variables

                Socket sock;


                ObjectInputStream in;

                ObjectOutputStream out;
                ClientRead cr;
                ClientWrite cw;

                public Vector<String> packs = new Vector<String>();

//classes and functions
                 TcpClient(Socket s) {

                        this.sock = s;
                        try
                        {
                            sock.setKeepAlive(true);
                        }
                        catch(Exception e)
                        {
                            System.out.print(e);
                        }
                        cr = new ClientRead();
                        cw = new ClientWrite();


                }
                public class ClientRead extends Thread {
                     public boolean nameRecieved = false;
                String playerName;
                    public void run(){
                        try{
                            in  = new ObjectInputStream(sock.getInputStream());
                            while(sock.isConnected())
                            {
                                String packetContents = (String) in.readObject();
                                 System.out.print("Received: " + packetContents + " from " + sock.getRemoteSocketAddress().toString() + '\n');
                                if(packetContents.charAt(0)=='1')
                                {
                                    String token= new String();
                                    int i = 1;
                                    while(packetContents.charAt(i)==' ')
                                    {
                                        i++;
                                    }
                                    while(packetContents.charAt(i)!=' ')
                                    {
                                        token+=packetContents.charAt(i);
                                        i++;
                                    }
                                    int playerId = Integer.parseInt(token);
                                    token = new String();
                                    while(packetContents.charAt(i)==' ')
                                    {
                                        i++;
                                    }
                                    while(packetContents.charAt(i)!=' ')
                                    {
                                        token+=packetContents.charAt(i);
                                        i++;
                                    }
                                    String playerName = token;
                                    token = new String();
                                    while(packetContents.charAt(i)==' ')
                                    {
                                        i++;
                                    }
                                    while(packetContents.charAt(i)!=' ')
                                    {
                                        token+=packetContents.charAt(i);
                                        i++;
                                    }
                                    float x = Float.parseFloat(token);
                                    token = new String();
                                    while(packetContents.charAt(i)==' ')
                                    {
                                        i++;
                                    }
                                    while(packetContents.charAt(i)!=' ')
                                    {
                                        token+=packetContents.charAt(i);
                                        i++;
                                    }
                                    float y = Float.parseFloat(token);
                                    for(int j = 0; j<playerList.size(); j++)
                                        if(playerList.get(j).id==playerId)
                                        {
                                            playerList.get(j).name=playerName;
                                           playerList.get(j).x=x;
                                           playerList.get(j).y=y;
                                          

                                        }
                                    addToQueue(packetContents);

                                } else if(packetContents.charAt(0)=='5'){

                                    String token= new String();
                                    int i = 1;
                                    while(packetContents.charAt(i)==' ')
                                    {
                                        i++;
                                    }
                                    while(packetContents.charAt(i)!=' ')
                                    {
                                        token+=packetContents.charAt(i);
                                        i++;
                                    }
                                    int pID = Integer.parseInt(token);
                                    token= new String();

                                    while(packetContents.charAt(i)==' ')
                                    {
                                        i++;
                                    }
                                    while(packetContents.charAt(i)!=' ')
                                    {
                                        token+=packetContents.charAt(i);
                                        i++;
                                    }
                                    int area = Integer.parseInt(token);

                                    for(int j = 0; j<playerList.size(); j++)
                                        if(playerList.get(j).id==pID)
                                        {
                                            playerList.get(j).area = area;

                                        }
                                    addToQueue(packetContents);
                                }else if(packetContents.charAt(0)=='9'){
                                    String token= new String();
                                    int i = 1;
                                    while(packetContents.charAt(i)==' ')
                                    {
                                        i++;
                                    }
                                    while(packetContents.charAt(i)!=' ')
                                    {
                                        token+=packetContents.charAt(i);
                                        i++;
                                    }
                                    int pID = Integer.parseInt(token);
                                    //token= new String();
                                    playerList.get(pID).Connected = false;
                                    addToQueue("$ " + token + " ");
                                    Thread.currentThread().sleep(10);
                                    clientList.get(pID).sock.close();
                                    clientList.get(pID).cw.join();
                                    clientList.get(pID).cr.join();
                                    System.out.print(pID + " D/C");
                                } else if(packetContents.charAt(0)=='8'){
                                    String token= new String();
                                    int i = 1;
                                    while(packetContents.charAt(i)==' ')
                                    {
                                        i++;
                                    }
                                    while(packetContents.charAt(i)!=' ')
                                    {
                                        token+=packetContents.charAt(i);
                                        i++;
                                    }
                                    int fID = Integer.parseInt(token);
                                    token= new String();

                                    while(packetContents.charAt(i)==' ')
                                    {
                                        i++;
                                    }
                                    while(packetContents.charAt(i)!=' ')
                                    {
                                        token+=packetContents.charAt(i);
                                        i++;
                                    }
                                    int toID = Integer.parseInt(token);
                                    System.out.print(packetContents + "\n");
                                    clientList.get(toID).packs.add(packetContents);
                                }else if(packetContents.charAt(0)=='6'){
                                    addToQueue(packetContents);
                                }else if(packetContents.charAt(0)=='#'){
                                    int i = 1;
                                    while(packetContents.charAt(i)==' ')
                                    {
                                        i++;
                                    }
                                    String pName = new String();
                                    while(packetContents.charAt(i)!=' ')
                                    {
                                        pName+=packetContents.charAt(i);
                                        i++;
                                    }
                                    playerName = pName;
                                    nameRecieved = true;
                                    
                                } else {

                               
                                //addToQueue(packetContents);
                                }
                            }
                        }
                        catch(Exception e){
                                System.out.print(e);
                    }
                }
        }
             public class ClientWrite extends Thread {
                    public void run() {
                        try{

                            out = new ObjectOutputStream(sock.getOutputStream());
                            out.flush();
                            while(sock.isConnected())
                            {
                                out.flush();
                                while(!packs.isEmpty())
                                {
                                    out.writeObject(packs.firstElement());
                                    System.out.print(packs.firstElement());
                                    packs.remove(0);
                                    out.flush();
                                }
                            }
                            //sock.close();
                            //playerList.get(MIN_PRIORITY)

                        }
                        catch(Exception e)
                        {
                            System.out.print(e);
                        }
                    }
                }
    }
}